home *** CD-ROM | disk | FTP | other *** search
- {
- Useful for transferring objects which have been registered to the clipboard or any global memory situation.
- Also could be used to make a copy of any streamable object. Merely stream the object to memory and then
- re-instantiate a new object through the use of a TStream.Get. Solves the
- problem of passing objects to another program because it removes any method pointer info.
-
- NOTE: This works only for streams which are not larger than 64K. In order
- to make this work for larger streams you have to ensure that your
- writes and puts (and gets and reads...) don't straddle each 64K boundary.
- I haven't added the pointer math to this unit yet.
- }
-
- { Author Robert Warren CIS ID 70303,537 }
-
- Unit MemStream;
-
- interface
-
- Uses WinTypes,WinProcs, WObjects;
-
- type
-
- PMemStream = ^TMemStream;
- TMemStream = object(TStream)
-
- Handle: Word;
- Address: Pointer;
- Size: Longint; { allocated size }
- Position: Longint; { current position in stream }
- AllocFlags: LongInt; { flags required when allocating / reallocating }
- FreeMemory: Boolean; { Flag indicating whether to free global
- memory when disposing of object }
-
- constructor Init(AllocSize: Longint; Flags: LongInt; FreeMem: Boolean);
- constructor InitWithHandle(aHandle: THandle; Flags: LongInt; FreeMem: Boolean);
- destructor Done; virtual;
- function GetPos: Longint; virtual;
- procedure Grow(howMuch: LongInt); virtual;
- function GetSize: Longint; virtual;
- procedure Read(var Buf; Count: Word); virtual;
- procedure Write(var Buf; Count: Word); virtual;
- procedure Seek(Pos: Longint); virtual;
- procedure Truncate; virtual;
- end;
-
- implementation
-
- {
- creates a memory stream of given size using the flags. The FreeMem argument
- is used to determine whether to delete the global block of memory when the
- object is disposed of. Sometime you don't want to delete the block if for
- example it has been placed in the clipboard or passed using DDE.
- }
- constructor TMemStream.Init(AllocSize: Longint; Flags: LongInt;FreeMem: Boolean);
- begin
- TStream.Init;
- Handle:=GlobalAlloc( Flags, AllocSize);
- Address:=GlobalLock(Handle); { so much for real mode }
- Size:=AllocSize;
- Position:=0;
- FreeMemory:= FreeMem;
- end;
-
- {
- same as above but allows for the creation of a object given an already
- allocated memory block. Perhaps some data FROM a clipboard
- }
- constructor TMemStream.InitWithHandle(aHandle: THandle; Flags: LongInt;FreeMem: Boolean);
- begin
- TStream.Init;
- Size:=GlobalSize(Handle);
- Address:=GlobalLock(Handle);
- Position:=0;
- FreeMemory:= FreeMem;
- end;
-
-
- destructor TMemStream.Done;
- begin
- TStream.Done;
- GlobalUnlock(Handle);
- If FreeMemory then GlobalFree(Handle);
- end;
-
- function TMemStream.GetPos: LongInt;
- begin
- GetPos:=Position;
- end;
-
- function TMemStream.GetSize: LongInt;
- begin
- GetSize:=Size;
- end;
-
-
- procedure TMemStream.Read(var Buf; Count: Word);
- var
- varAddress: PChar;
- stAddress: PChar;
- i: LongInt;
- begin
- varAddress:=@Buf;
- stAddress:=PChar(MakeLong(Position+LoWord(LongInt(Address)),HiWord(LongInt(Address))));
- for i:=0 to Count -1 do
- varAddress[i]:=stAddress[i];
- inc(Position,Count);
- end;
-
- procedure TMemStream.Grow(HowMuch: LongInt);
- begin
- GlobalUnlock(Handle);
- Inc(Size,HowMuch);
- GlobalRealloc(Handle, Size, AllocFlags);
- GlobalLock(Handle);
- end;
-
- procedure TMemStream.Write(var Buf; Count: Word);
- var
- varAddress: PChar;
- stAddress: PChar;
- i: LongInt;
- growSize: Integer;
- begin
-
- if Position + Count >= Size then
- begin
- if count < 1023
- then growSize:=1024
- else growSize:=count + 1;
-
- Grow(growSize);
- end;
-
- varAddress:=@Buf;
- stAddress:=PChar(MakeLong(Position+LoWord(LongInt(Address)),HiWord(LongInt(Address))));
- for i:=0 to Count -1 do
- stAddress[i]:=varAddress[i];
- inc(Position,Count);
- end;
-
- procedure TMemStream.Seek(Pos: Longint);
- begin
- Position:=Pos;
- end;
-
- procedure TMemStream.Truncate;
- begin
- GlobalUnlock(Handle);
- GlobalReAlloc(Handle,Position,AllocFlags);
- Address:=GlobalLock(Handle);
- Size:=Position;
- end;
-
- end.
-